package com.atguigu.controller;

import com.atguigu.bean.Employee;
import com.atguigu.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Collection;

/**
 * @author 伟哥
 * @date 2021-05-22 18:45
 */
@Controller
public class AjaxController {

    @Autowired
    EmployeeDao employeeDao;

    /**
     * 【1 - 1】注解@ResponseBody：
     * 标注位置：方法、类
     *  ★★★作用：
     *      1）、将返回值的数据，放在《响应体》，返回给前端页面
     *      2）、如果，返回结果是【对象】，jackson包会【自动将对象，转为json格式】
     *
     *  测试：直接访问请求地址/getallajax
     * @return
     */
    @ResponseBody
    @RequestMapping("/getallajax")
    public Collection<Employee> ajaxGetAllEmploys(){
        // 获取全部员工
        Collection<Employee> all = employeeDao.getAll();
        // 返回all：全部员工
        return all;
    }

    /**
     * 【1 - 2】注解@ResponseBody：高级用法
     *      直接，在返回值写页面
     *
     *  测试：直接访问请求地址/testResponseBody
     */
    @ResponseBody
    @RequestMapping("/testResponseBody")
    public String testResponseBody(){
        return "<h1>success</h1>";
    }

    /**
     * 【2】注解@RequestBody：接收【请求体】
     * 标注位置：方法参数
     *  ★★★作用：
     *      1）、获取，请求中的【请求体】内容
     *      请求体：能够包含请求体内容的，只有form表单的POST提交。ps:GET提交，数据在url地址
     *
     * 注解：在参数上使用@RequestParam：获取请求参数中的值
     *
     * 测试：testOther.jsp
     * @return
     */
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        //获取请求体的内容：name=nihao&password=123456
        System.out.println("获取请求体的内容："+body);
        return "success";
    }
    /**
     * 【3】注解@RequestBody【高级应用】：接收请求体中的json数据
     *      RequestBody接收【请求体】的json格式，并使用jackson【自动封装为JavaBean对象】
     *
     * 测试：testOther.jsp
     * @return
     */
    @RequestMapping("/testRequestBodyJson")
    public String testRequestBody(@RequestBody Employee employee){
        System.out.println("获取请求体的内容："+employee);
        return "success";
    }

    /**
     * 【4】HttpEntity<String>获取【请求头】+【请求体】
     * 使用方式：
     *      方法入参，直接输入HttpEntity<String> str，使用即可
     *
     * 效果：
     *      比注解@RequestBody获取请求体，更加强大。它还可以获取请求头信息
     *      注解@RequestHeader("key")只能获取某一个请求头
     *
     * 测试：testOther.jsp
     * @return
     */
    @RequestMapping("/testHttpEntity")
    public String testHttpEntity(HttpEntity<String> str){
        System.out.println("获取请求内容："+str);
        return "success";
    }

    /**
     * 【5】ResponseEntity<T>：返回自定义响应。既携带【响应头信息】，又携带【响应体信息】
     *     泛型：代表：响应体中内容的类型
     *
     * 效果：
     *      比注解@RequestBody更加强大。
     *      返回的数据中，既可以携带【响应头信息】，也可以携带【响应体信息】
     *
     * 使用步骤：
     *      1、创建new ResponseEntity<String>(@Nullable T body, @Nullable MultiValueMap<String, String> headers, Object status)
     *          ResponseEntity<String>(响应体, 响应头, 状态码)
     *      2、设置响应体、响应头、状态码等
     *      3、返回ResponseEntity
     *
     * 测试：直接访问请求地址/testResponseEntity
     * @return
     */
    @RequestMapping("/testResponseEntity")
    public ResponseEntity<String> testHttpEntity(){
        String body = "<h1>success</h1>";

        MultiValueMap<String, String> headers = new HttpHeaders();
        headers.add("Set-Cookie","username=hahahahah");

        return new ResponseEntity<String>(body, headers, HttpStatus.OK);
    }

    /**
     * 【6案例】ResponseEntity<T>：返回自定义响应。
     *      使用ResponseEntity，完成【下载】功能。
     *      ps：SpringMVC的下载完成度，比较辣鸡，不如原生API
     *
     * 案例要求：下载项目下的log4j2.xml文件
     *
     * 1、将ResponseEntity<T>中的泛型，设置为byte[]，对应下载流
     * 2、得到log4j2.xml的路径
     *      1）、服务器上线之后，项目就会在服务器的电脑
     *      2）、所以需要找到，log4j2.xml文件的真实路径
     *      3）、使用原生API（HttpServletRequest request）获取路径
     * 3、使用io流，读取文件
     * 4、读取io流中的数据
     * 5、自定义响应头★★★
     *      1）、浏览器能否下载文件，要看【响应头】中的信息，所以我们需要自定义响应头的信息
     *      2）、new HttpHeaders 自定义响应头的信息
     *      3）、"Content-Disposition","attachment;filename="
     * 6、将自定义的响应头设置进ResponseEntity，并返回
     *
     * @return
     */
    @RequestMapping("/download")
    public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception {
        // 2、得到README.md文件的路径
        String realPath = request.getServletContext().getRealPath("/WEB-INF/classes/log4j2.xml");
        // 3、使用io流，读取文件
        FileInputStream is = new FileInputStream(realPath);
        // 4、使用byte数组tmp，接收io流中的数据
        byte[] tmp = new byte[is.available()];
        is.read(tmp);is.close();


        // 5、自定义响应头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Disposition","attachment;filename="+"log4j2.xml");

        return new ResponseEntity<byte[]>(tmp,httpHeaders,HttpStatus.OK);
    }
}
